/* Teach Tool  - Structural Dynamics
 * Copyright (C) 2009: Fabian Gerold, www.fabiangerold.de
 *
 * This file may be licensed under the terms of of the
 * GNU General Public License Version 3 (the "GPL").
 * 
 * Software distributed under the License is distributed 
 * on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either 
 * express or implied. See the GPL for the specific language 
 * governing rights and limitations.
 *
 * You should have received a copy of the GPL along with this 
 * program. If not, go to http://www.gnu.org/licenses/gpl.html
 * or write to the Free Software Foundation, Inc., 
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

#include <QtGui>

#include "EMSWidget.h"
#include "mass.h"
#include "springDamp.h"
#include "../src_common/System.h"

class Force : public QGraphicsItem
{
public:
	Force( int x, int y )
	{
		m_x = x;
		m_y = y;
		m_scale = 1;
	}
	QRectF boundingRect() const { return QRectF( m_x-100, m_y-12, 200, 24 ); }
	void paint( QPainter* painter, const QStyleOptionGraphicsItem*, QWidget* )
	{
		QPainterPath path;
		path.moveTo( m_x, m_y-4 );
		path.lineTo( m_x+70*m_scale, m_y-4 );
		path.lineTo( m_x+70*m_scale, m_y-12 );
		path.lineTo( m_x+100*m_scale, m_y );
		path.lineTo( m_x+70*m_scale, m_y+12 );
		path.lineTo( m_x+70*m_scale, m_y+4 );
		path.lineTo( m_x, m_y+4 );
		path.lineTo( m_x, m_y-4 );

		painter->fillPath( path, QColor( 241, 165, 186 ) );
	}
	void setScale( double scale )
	{
		m_scale = scale;
		update();
	}
	
private:
	int			m_x;
	int			m_y;
	double		m_scale;
};


EMSWidget::EMSWidget( System* sys )
{
	m_system = sys;
    m_scene = new QGraphicsScene( this );
    m_scene->setItemIndexMethod( QGraphicsScene::NoIndex );
    m_scene->setSceneRect(-50, 0, 500, 180);
    setScene( m_scene );
    setCacheMode( CacheBackground );
    setRenderHint( QPainter::Antialiasing );
    setTransformationAnchor( AnchorUnderMouse );
    setResizeAnchor( AnchorViewCenter );
	setFrameStyle( QFrame::Plain );

    m_mass = new Mass( this );
    m_mass->initPos( 300, 80 );
	m_scene->addItem( m_mass );
	
    m_spring_damp = new SpringDamp();
    m_spring_damp->initPos( 30, 80 );
	m_scene->addItem( m_spring_damp );

	m_force = new Force( 300, 20 );
	m_force_visible = false;

	// disp meter
	QPen pen( QColor( 200, 200, 200 ) );
	m_scene->addLine( 200, 160, 400, 160, pen );
	for( int i=0; i<=20; i++ )
	{
		m_scene->addLine( 200+i*10, 155, 200+i*10, 160, pen );
	}

	m_scene->addLine( 200, 150, 200, 160, pen );
	m_scene->addLine( 300, 150, 300, 160, pen );
	m_scene->addLine( 400, 150, 400, 160, pen );
	QGraphicsTextItem* left = m_scene->addText( "-1.0" );
	left->setPos( 190, 160 );
	left->setDefaultTextColor( QColor( 160, 160, 160 ) );

	QGraphicsTextItem* mid = m_scene->addText( "0.0" );
	mid->setPos( 295, 160 );
	mid->setDefaultTextColor( QColor( 160, 160, 160 ) );

	QGraphicsTextItem* right = m_scene->addText( "1.0   [m]" );
	right->setPos( 390, 160 );
	right->setDefaultTextColor( QColor( 160, 160, 160 ) );


    setMinimumSize( 500, 180 );

	connect( m_system, SIGNAL( signalSetDisp( double, double ) ),	this, SLOT( slotSetDisp(double,double) ) );
	connect( m_system, SIGNAL( signalSetDragDisp( double ) ),		this, SLOT( slotSetDragDisp(double) ) );
	connect( m_system, SIGNAL( signalSetSpring( double ) ),			this, SLOT( slotSetSpring(double) ) );
	connect( m_system, SIGNAL( signalSetMass( double ) ),			this, SLOT( slotSetMass(double) ) );
	connect( m_system, SIGNAL( signalSetDamp( double ) ),			this, SLOT( slotSetDamp(double) ) );
	connect( m_system, SIGNAL( signalResetDisp() ),					this, SLOT( slotResetDisp() ) );

}

void EMSWidget::showGroundMeter()
{
	// disp meter
	QPen pen( QColor( 200, 200, 200 ) );
	m_scene->addLine( -20, 160, 80, 160, pen );
	for( int i=0; i<=10; i++ )
		m_scene->addLine( -20+i*10, 155, -20+i*10, 160, pen );

	m_scene->addLine( -20, 150, -20, 160, pen );
	m_scene->addLine( 30, 150, 30, 160, pen );
	m_scene->addLine( 80, 150, 80, 160, pen );

	//QGraphicsTextItem* info = m_scene->addText( "Ground displacement: " );
	//info->setPos( -130, 170 );
	//info->setDefaultTextColor( QColor( 160, 160, 160 ) );

	QGraphicsTextItem* left = m_scene->addText( "-0.5" );
	left->setPos( -25, 160 );
	left->setDefaultTextColor( QColor( 160, 160, 160 ) );

	QGraphicsTextItem* mid = m_scene->addText( "0.0" );
	mid->setPos( 25, 160 );
	mid->setDefaultTextColor( QColor( 160, 160, 160 ) );

	QGraphicsTextItem* right = m_scene->addText( "0.5   [m]" );
	right->setPos( 75, 160 );
	right->setDefaultTextColor( QColor( 160, 160, 160 ) );
}

void EMSWidget::slotSetDisp( double disp, double ground_disp )
{
	m_mass->setDisp( disp );
	m_spring_damp->setDisp( disp, ground_disp );
}

void EMSWidget::slotResetDisp()
{
	m_mass->setDisp( 0 );
	m_spring_damp->resetDisp();
}


void EMSWidget::slotSetDragDisp( double disp )
{
	m_spring_damp->setDisp( disp, 0 );
}

void EMSWidget::slotSetForce( double force )
{
	m_force->setScale( force );
	//m_spring_damp->setDisp( disp, ground_disp );
}
void EMSWidget::slotSetForceVisible( bool visible )
{
	if( visible && !m_force_visible )
	{
		m_scene->addItem( m_force );
		m_force_visible = true;
	}
	else if( !visible && m_force_visible )
	{
		m_scene->removeItem( m_force );
		m_force_visible = false;
	}
	update();	
}

void EMSWidget::slotSetMass( double m )
{
	m_mass->setMass( m );
	update();
}
void EMSWidget::setMassDragable( bool dragable )
{
	m_mass->setDragable( dragable );
}

void EMSWidget::slotSetSpring( double k )
{
	m_spring_damp->setSpring( k );
}

void EMSWidget::slotSetDamp( double d )
{
	m_spring_damp->setDamp( d );
}

QSize EMSWidget::sizeHint () const
{
	return QSize( 600, 180 );
}

void EMSWidget::resizeEvent( QResizeEvent* )
{
	fitInView ( QRectF( -50, 0, 500, 180), Qt::KeepAspectRatio );
}


void EMSWidget::pressMass()
{
	//emit( massPressed() );
	m_system->slotStop();
}
void EMSWidget::dragMass( double dx )
{
	//emit( massDragged( dx ) );
	m_system->slotSetDragDisp( dx );
}
void EMSWidget::releaseMass( double dx )
{
	//emit( massReleased( dx ) );
	m_system->slotStart( dx );
}
